// #include "Sem_V1.hpp"
// #include <unistd.h>
// #include <ctime>
// #include <cstdio>

// int main()
// {
//     SemaphoreBuilder sb;
//     auto fsem = sb.SetVar(1).Build(BUILD_SEM, 1);
    
//     srand(time(0) ^ getpid());
//     pid_t pid = fork();

//     // 期望：父子打印时，C或者F成对出现
//     if(pid == 0)
//     {
//         auto csem = sb.Build(GET_SEM);
//         while(true)
//         {
//             csem->P();
//             // 临界区代码
//             printf("C");
//             usleep(rand() % 95270);
//             fflush(stdout);
            
//             printf("C");
//             usleep(rand() % 43990);
//             fflush(stdout);
            
//             csem->V();
//         }
//     }
//     while(true)
//     {
//         fsem->P();

//         printf("F");
//         usleep(rand() % 95270);    
//         fflush(stdout);

//         printf("F");
//         usleep(rand() % 43990);
//         fflush(stdout);
        
//         fsem->V();
//     }
    
//     return 0; 
// }





#include "Sem_V2.hpp"
#include <unistd.h>
#include <ctime>
#include <cstdio>

int main()
{   
    // 1. 基于抽象接口类的具体建造类
    std::shared_ptr<SemaphoreBuilder> builder = std::make_shared<ConcreteSemaphoreBuilder>();
    // 2. 指挥者对象
    std::shared_ptr<Director> director = std::make_shared<Director>();
    // 3. 在指挥者指导下，完成建造过程
    director->Construct(builder, BUILD_SEM, 0600, 3, {1, 2, 3});
    // 4. 完成对象创建过程，获取对象
    auto fsem = builder->GetSem();

    // sleep(10);
        
    srand(time(0) ^ getpid());
    pid_t pid = fork();

    // 期望：父子打印时，C或者F成对出现
    if(pid == 0)
    {
        director->Construct(builder, GET_SEM, 0600, 3, {1, 2, 3});
        auto csem = builder->GetSem();
        while(true)
        {
            csem->P(0);
            // 临界区代码
            printf("C");
            usleep(rand() % 95270);
            fflush(stdout);
            
            printf("C");
            usleep(rand() % 43990);
            fflush(stdout);
            
            csem->V(0);
        }
    }
    while(true)
    {
        fsem->P(0);

        printf("F");
        usleep(rand() % 95270);    
        fflush(stdout);

        printf("F");
        usleep(rand() % 43990);
        fflush(stdout);
        
        fsem->V(0);
    }
    return 0; 
}